feat(miner-foundation): extract reward-risk scoring into gittensory-engine (#2281) - #3985
Conversation
…ngine (JSONbored#2281) Move the reward/risk reasoning signals into packages/gittensory-engine/src/reward-risk.ts so the gittensory-miner can rank candidate work locally with the same logic the maintainer-side gate computes. Closes JSONbored#2281.
Add test/unit/reward-risk-engine-branch-coverage.test.ts driving the deterministic tie-break / defensive branches the pre-existing suite never exercised (now measured because the module is new to the engine package): the fit.opportunities map, the analysisRank and topActions localeCompare/ ACTION_RANK ties, the maintainer non-low-queue readiness score, both reviewChurnRisk tiers, and the equal-multiplier label sort. Hoist the actions sort into its own statement so the deterministic secondary action-rank tie-break can be v8-ignored (the prior inline /* v8 ignore next */ did not suppress the branch). Behavior is unchanged.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-07 08:52:25 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 1 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3985 +/- ##
==========================================
+ Coverage 93.71% 93.73% +0.02%
==========================================
Files 373 374 +1
Lines 35047 35050 +3
Branches 12839 12839
==========================================
+ Hits 32843 32853 +10
+ Misses 1584 1583 -1
+ Partials 620 614 -6
🚀 New features to boost your workflow:
|
Summary
Extracts the deterministic reward/risk reasoning signals out of
src/signals/reward-risk.tsintopackages/gittensory-engine/src/reward-risk.ts, so the gittensory-miner can rank candidate work locally with the same logic the maintainer-side gate computes. MovesbuildRepoRewardRisk,buildContributorRewardRiskStrategy,buildMaintainerNoiseReport,buildPullRequestReviewability,rewardRiskFreshnessInternals, and every public type, and re-exports them from the engine barrel.src/signals/reward-risk.tsbecomes a shim that imports the engine implementation via its relative source path (../../packages/gittensory-engine/src/reward-risk.js) — matching the merged #2276/#2278/#2282 shims, not the published@jsonbored/gittensory-enginespecifier — so no tsconfig path, vitest alias, or root dependency is introduced.Closes #2281.
Why a wrapping shim instead of a pure re-export
Unlike the earlier self-contained extractions, reward-risk sits on top of the maintainer signal stack in
src/signals/engine.ts(buildRoleContext,buildLaneAdvice,buildCollisionReport,buildQueueHealth,buildRepoFitRecommendation,buildContributorIntakeHealth,buildPullRequestReviewIntelligence) plusisFailingCheckSummaryfromsrc/signals/local-branch.ts. Those builders are not extracted yet and are far too large to port under the size cap, and the engine package must never import fromsrc/. So the engine module takes them as an injectedRewardRiskEngineDeps, and the shim binds the realsrcbuilders and threads them in — every existing importer keeps calling the four builders with their original signatures. Once those builders gain engine homes, a follow-up can drop the injection and collapse the shim back to a plain re-export.The injected builders bind with no casts: their argument records are wider than (assignable to) the engine's mirror types, and their richer return types are covariantly assignable to the narrowed views the module reads. The engine-side types live in
packages/gittensory-engine/src/types/reward-risk-types.ts(hand-kept mirrors, same pattern aspredicted-gate-types.ts); the record mirrors are full verbatim copies because the reward-risk tests build those records as inline object literals. The real runtime objects pass straight through the injected builders, so behavior is identical to the pre-extraction file.Coverage
Because the module is new to the engine package, codecov/patch measures every branch — including a handful of deterministic tie-break / defensive branches the pre-existing suite never exercised.
test/unit/reward-risk-engine-branch-coverage.test.tsdrives each of them (thefit.opportunitiesmap, theanalysisRank/topActionslocaleCompare/ACTION_RANKties, the maintainer non-low-queue readiness score, bothreviewChurnRisktiers, and the equal-multiplier label sort). The one genuinely unreachable branch — the secondary action-rank presentation tie-break — is hoisted into its own statement and/* v8 ignore */-suppressed (the prior inline ignore did not suppress it). The engine module is now 100% branch / line / function.Test plan
npm run typecheck(exit 0) — and again withpackages/gittensory-engine/dist/moved aside (resolves via source, not a stale build)npm run test:coverage(11190 passed; enginereward-risk.ts321/321 branches, 180/180 lines, 67/67 functions; shim 100%)npm run ui:typecheck,npm run ui:lint(0 errors),npm run ui:test(71)npm run rees:test(1189)git diff --checkclean